﻿(*
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser General Public License
 * (LGPL) version 2.1 which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/lgpl-2.1.html
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *)

namespace TfsEngineImpl

open System
open TfsEngine

type WorkspaceInfo(inner: Microsoft.TeamFoundation.VersionControl.Client.WorkspaceInfo) =
    
    interface IWorkspaceInfo with
        member this.ServerUri
            with get() =
                inner.ServerUri

    member val InnerObject = inner :> obj with get

type Workspace(inner: Microsoft.TeamFoundation.VersionControl.Client.Workspace) =

    interface IWorkspace with
        member this.GetPendingChanges items =
            let specs =
                items
                |> Seq.map (fun i -> Microsoft.TeamFoundation.VersionControl.Client.ItemSpec(i, Microsoft.TeamFoundation.VersionControl.Client.RecursionType.None))
                |> Seq.toArray

            inner.GetPendingChanges(specs)
            |> Seq.map (fun pend -> { LocalItem = pend.LocalItem} )

        member this.GetLocalVersions items =
            let specs =
                items
                |> Seq.map (fun i -> Microsoft.TeamFoundation.VersionControl.Client.ItemSpec(i, Microsoft.TeamFoundation.VersionControl.Client.RecursionType.None))
                |> Seq.toArray

            inner.GetLocalVersions(specs, false)
            |> Seq.map (fun localItens ->
                localItens
                |> Seq.map (fun local -> { Item = local.Item; Version = local.Version} )
            )

        member this.GetServerItemForLocalItem item =
            inner.GetServerItemForLocalItem item

type VersionControlServer(inner: Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer) =

    interface IVersionControlServer with
        member this.GetWorkspace workstationInfo =
            match workstationInfo with
                | :? WorkspaceInfo as wi ->
                    let wsp = inner.GetWorkspace(wi.InnerObject :?>  Microsoft.TeamFoundation.VersionControl.Client.WorkspaceInfo )
                    Workspace(wsp) :> IWorkspace
                | _ -> failwith "Unexpected object type"


type TfsTeamProjectCollection(inner: Microsoft.TeamFoundation.Client.TfsTeamProjectCollection) =

    interface ITfsTeamProjectCollection with
        member this.GetVersionControlServer () =
            let vcs = inner.GetService<Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer>()
            VersionControlServer(vcs) :> IVersionControlServer

        member this.Dispose() =
            inner.Dispose()

type Engine() =

    interface ITfsEngine with

//        member this.GetLocalWorkspaceInfo path = //: string -> IWorkstationInfo option
//            let wi = Microsoft.TeamFoundation.VersionControl.Client.Workstation.Current.GetLocalWorkspaceInfo(path)
//
//            if wi = null then
//                None
//            else
//                Some(WorkspaceInfo(wi) :> IWorkspaceInfo)

        member this.GroupByLocalWorkspaceInfo paths =
            let grouped =
                paths
                |> Seq.groupBy (fun file -> Microsoft.TeamFoundation.VersionControl.Client.Workstation.Current.GetLocalWorkspaceInfo(file) )
                |> Seq.map (fun g ->
                    let wi = 
                        if (fst g) = null then
                            None
                        else
                            Some(WorkspaceInfo(fst g) :> IWorkspaceInfo)
                    wi, (snd g |> Seq.toList)
                )
                |> Seq.toList

            grouped


            



        member this.TfsTeamProjectCollection serverUri =
            let tpc = new Microsoft.TeamFoundation.Client.TfsTeamProjectCollection(serverUri)
            new TfsTeamProjectCollection(tpc) :> ITfsTeamProjectCollection

